﻿using System.Data.Objects;
using System.Web;
using Microsoft.Practices.Unity;

namespace eShop.Domain
{
    public class DomainRepositoryFactory
    {
        #region UnityContainer Singleton

        private const string InstanceContextName = "RepositoryContainerInstance";

        private static IUnityContainer _repositoryContainerInstance;

        private static IUnityContainer RepositoryContainerInstance
        {
            get
            {
                if (HttpContext.Current == null)
                {
                    if (_repositoryContainerInstance == null)
                    {
                        _repositoryContainerInstance = InitializeRepositoryContainer();
                    }
                    
                    return _repositoryContainerInstance;
                }

                if (!HttpContext.Current.Items.Contains(InstanceContextName))
                {
                    HttpContext.Current.Items.Add(InstanceContextName, InitializeRepositoryContainer());
                }
               
                return (IUnityContainer)HttpContext.Current.Items[InstanceContextName];
            }
        }

        private static IUnityContainer InitializeRepositoryContainer()
        {
            IUnityContainer unityContainer = new UnityContainer();

            //TODO Itt kell példányosítani a valós OC-t:
            //var objectContext = new DomainObjectContext();
            var objectContext = new ObjectContext("");

            unityContainer.RegisterInstance(unityContainer);
            unityContainer.RegisterInstance<ObjectContext>(objectContext);
            unityContainer.RegisterType<IRepository, Repository>();

            InitializeDomainRepositories(unityContainer);

            return unityContainer;
        }

        protected static void InitializeDomainRepositories(IUnityContainer unitiyContainer)
        {
            //unityContainer.RegisterType<IBusinessRuleValidator, BusinessRuleValidator>();
        }

        #endregion

        #region Factory static methods

        public static IUnityContainer CreateChildContainer()
        {
            return RepositoryContainerInstance.CreateChildContainer();
        }

        public static T GenerateImplementation<T>()
        {
            return RepositoryContainerInstance.Resolve<T>();
        }

        public T BuildUp<T>(T objectToBuildUp)
        {
            return RepositoryContainerInstance.BuildUp(objectToBuildUp);
        }

        #endregion

        public static void TearDown()
        {
            var objectContext = GenerateImplementation<ObjectContext>();
            objectContext.Dispose();
        }
    }
}
